#include "shortcutsettings.h"
#include <QTest>
#include <QFont>

ShortcutSettings::ShortcutSettings(QWidget * parent) : SettingsMenuItem(parent)
{
    initializeButtons();
    setMouseTracking(true);
}

void ShortcutSettings::initializeButtons() {
    QVBoxLayout * mainLayout=new QVBoxLayout(this);
    setLayout(mainLayout);
    /*QLayout * currentLayout=new QHBoxLayout();
    currentLayout->addWidget(new QLabel("Up",this));
    KeyDialog * dialog=new KeyDialog(this);
    dialog->setOneKey(true);
    connect(dialog,SIGNAL(okSelected()),this,SLOT(show()));
    dialog->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    dialog->hide();
    dialog->setMinimumSize(300,200);
    changeUp=new Button(QIcon(), "Change Key", this, dialog);
    currentLayout->addWidget(changeUp);
    addRow(changeUp);

    mainLayout->addItem(currentLayout);
    mainLayout->setAlignment(currentLayout,Qt::AlignTop);*/
    QLayout * currentLayout=new QHBoxLayout();
    QLabel * currentLabel=new QLabel("Key Name",this);
    QFont font=QFont();
    font.setUnderline(true);
    font.setBold(true);
    currentLabel->setFont(font);
    currentLayout->addWidget(currentLabel);
    currentLabel=new QLabel("Key Binding",this);
    currentLabel->setFont(font);
    currentLayout->addWidget(currentLabel);
    currentLabel=new QLabel("Click To Change",this);
    currentLabel->setFont(font);
    currentLayout->addWidget(currentLabel);
    layout()->addItem(currentLayout);
    layout()->setAlignment(currentLayout,Qt::AlignTop);

    buttons=QList<Button *>();
    font.setBold(false);
    font.setPointSize(20);
    setStyleSheet("font-size: 20px;");
    changeUp=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    changeUp->setIconSize(QSize(256,36));
    upLabel=new QLabel(this);
    addButton("Up",upLabel,changeUp);

    changeDown=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    changeDown->setIconSize(QSize(256,36));
    downLabel=new QLabel(this);
    addButton("Down",downLabel,changeDown);

    changeLeft=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    changeLeft->setIconSize(QSize(256,36));
    leftLabel=new QLabel(this);
    addButton("Left",leftLabel,changeLeft);

    changeRight=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    changeRight->setIconSize(QSize(256,36));
    rightLabel=new QLabel(this);
    addButton("Right",rightLabel,changeRight);

    volumeUp=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    volumeUp->setIconSize(QSize(256,36));
    volumeUpLabel=new QLabel(this);
    addButton("Volume Up",volumeUpLabel,volumeUp);

    volumeDown=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    volumeDown->setIconSize(QSize(256,36));
    volumeDownLabel=new QLabel(this);
    addButton("Volume Down",volumeDownLabel,volumeDown);

    changeHome=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    changeHome->setIconSize(QSize(256,36));
    homeLabel=new QLabel(this);
    addButton("Home",homeLabel,changeHome);

    changeBack=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    changeBack->setIconSize(QSize(256,36));
    backLabel=new QLabel(this);
    addButton("Back",backLabel,changeBack);

    changeNowPlaying=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    changeNowPlaying->setIconSize(QSize(256,36));
    nowPlayingLabel=new QLabel(this);
    addButton("Now Playing",nowPlayingLabel,changeNowPlaying);

    changeSelect=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    changeSelect->setIconSize(QSize(256,36));
    selectLabel=new QLabel(this);
    addButton("Select",selectLabel,changeSelect);

    /*changeSecondary=new Button(QIcon(":/imgs/3F00Button_ChangeKey.png"), "", this);
    changeSecondary->setIconSize(QSize(256,36));
    secondaryLabel=new QLabel(this);
    addButton("Secondary Select",secondaryLabel,changeSecondary);*/

    QHBoxLayout * horizontalLayout=new QHBoxLayout();
    QList<Button *> * list=new QList<Button *>();
    saveButton = new Button(QIcon(":/imgs/3F00Button_Save.png"),"",this,NULL);
    saveButton->setIconSize(QSize(110,48));
    horizontalLayout->addWidget(saveButton);
    list->append(saveButton);
    cancelButton = new Button(QIcon(":/imgs/3F00Button_Cancel.png"),"",this);
    cancelButton->setIconSize(QSize(110,48));
    horizontalLayout->addWidget(cancelButton);
    list->append(cancelButton);
    addRow(list);
    mainLayout->addItem(horizontalLayout);
    foreach(Button * button, buttons) {
        addDialog(button);
    }
    loadBindings();
}

void ShortcutSettings::addButton(QString name, QLabel * label, Button * button) {
    QLayout * currentLayout=new QHBoxLayout();
    currentLayout->addWidget(new QLabel(name,this));
    currentLayout->addWidget(label);
    currentLayout->addWidget(button);
    addRow(button);
    button->setItem(label);
    layout()->addItem(currentLayout);
    layout()->setAlignment(currentLayout,Qt::AlignTop);
    buttons.append(button);
}

void ShortcutSettings::addDialog(Button *button) {
    KeyDialog * dialog=new KeyDialog(this);
    dialog->setOneKey(true);
    connect(dialog,SIGNAL(okSelected(KeyDialog *)),this,SLOT(activate()));
    connect(dialog,SIGNAL(okSelected(KeyDialog *)),this,SLOT(updateShortcut(KeyDialog*)));
    dialog->setWindowFlags(Qt::Dialog|Qt::FramelessWindowHint |Qt::WindowStaysOnTopHint);
    dialog->hide();
    dialog->setMinimumSize(300,200);
    QLabel * label=qobject_cast<QLabel *>(button->getItem());
    hash.insert(dialog,label);
    button->setItem(dialog);
}

void ShortcutSettings::save() {
    save("up",changeUp);
    save("down",changeDown);
    save("left",changeLeft);
    save("right",changeRight);
    save("volumeUp",volumeUp);
    save("volumeDown",volumeDown);
    save("home",changeHome);
    save("back",changeBack);
    save("nowPlaying",changeNowPlaying);
    save("select",changeSelect);
    //save("secondary",changeSecondary);
    KeyBindings::loadKeyBindings();
    emit completed();
}

void ShortcutSettings::save(QString name, Button *button) {
    KeyDialog * dialog=qobject_cast<KeyDialog *>(button->getItem());

    if(dialog) {
        qDebug() << getModifierString(dialog->getModifiers());
        QString query="UPDATE shortcuts SET key='"+dialog->getText()+"', modifierKeys='"+QString::number(dialog->getModifiers())+"' WHERE function='"+name+"'";
        Querier::getResult(query);
        qDebug() <<query;
    }
}

void ShortcutSettings::cancel() {
    loadBindings();
    emit completed();
}

void ShortcutSettings::buttonSelected() {
    if(getCurrentButton()==saveButton) {
        save();
    } else if(getCurrentButton()==cancelButton) {
        cancel();
    }
    else {
        QObject * object=getCurrentButton()->getItem();
        KeyDialog * keyDialog = qobject_cast<KeyDialog *>(object);
        qDebug() <<"key dialog "<<keyDialog;
        if(keyDialog) {
            keyDialog->move(300,100);
            deactivate();
            keyDialog->show();
        }
    }
}

void ShortcutSettings::show() {
    SettingsMenuItem::show();
}

void ShortcutSettings::loadBindings() {
    ((KeyDialog *)changeUp->getItem())->setKey(KeyBindings::upKey[0],KeyBindings::upKey[1]);
    ((KeyDialog *)changeDown->getItem())->setKey(KeyBindings::downKey[0],KeyBindings::downKey[1]);
    ((KeyDialog *)changeLeft->getItem())->setKey(KeyBindings::leftKey[0],KeyBindings::leftKey[1]);

    ((KeyDialog *)changeRight->getItem())->setKey(KeyBindings::rightKey[0],KeyBindings::rightKey[1]);
    ((KeyDialog *)volumeUp->getItem())->setKey(KeyBindings::volumeUpKey[0],KeyBindings::volumeUpKey[1]);
    ((KeyDialog *)volumeDown->getItem())->setKey(KeyBindings::volumeDownKey[0],KeyBindings::volumeDownKey[1]);

    ((KeyDialog *)changeHome->getItem())->setKey(KeyBindings::homeKey[0],KeyBindings::homeKey[1]);
    ((KeyDialog *)changeBack->getItem())->setKey(KeyBindings::backKey[0],KeyBindings::backKey[1]);
    ((KeyDialog *)changeNowPlaying->getItem())->setKey(KeyBindings::nowPlayingKey[0],KeyBindings::nowPlayingKey[1]);
    ((KeyDialog *)changeSelect->getItem())->setKey(KeyBindings::selectKey[0],KeyBindings::selectKey[1]);
   // ((KeyDialog *)changeSecondary->getItem())->setKey(KeyBindings::secondaryKey[0],KeyBindings::secondaryKey[1]);
    foreach(KeyDialog * dialog, hash.keys()) {
        updateShortcut(dialog);
    }
}

void ShortcutSettings::saveTest() {
    QTest::mouseMove(volumeUp);
    emit buttonEntered(volumeUp);
    QTest::qWait(500);
    QTest::mouseClick(volumeUp,Qt::LeftButton);
    QTest::qWait(1000);
    KeyDialog * dialog=(KeyDialog *)volumeUp->getItem();
    //QTest::qWaitForWindowShown(dialog);
    QTest::keyPress(dialog,Qt::Key_7,Qt::NoModifier);
    QTest::qWait(1000);
    QTest::mouseMove(saveButton);
    emit buttonEntered(saveButton);
    QTest::qWait(500);
    QTest::mouseClick(saveButton,Qt::LeftButton);

}

void ShortcutSettings::assertSaved() {
    QCOMPARE(KeyBindings::volumeUpKey[0],(int)Qt::Key_7);
    QCOMPARE(KeyBindings::volumeUpKey[1],(int)Qt::NoModifier);
    QTest::mouseMove(volumeUp);
    emit buttonEntered(volumeUp);
    QTest::qWait(500);
    QTest::mouseClick(volumeUp,Qt::LeftButton);
    QTest::qWait(1000);
    KeyDialog * dialog=(KeyDialog *)volumeUp->getItem();
    QTest::keyPress(dialog,Qt::Key_Plus,Qt::ShiftModifier);
    QTest::mouseMove(saveButton);
    emit buttonEntered(saveButton);
    QTest::qWait(500);
    QTest::mouseClick(saveButton,Qt::LeftButton);
}

void ShortcutSettings::cancelTest() {
    QTest::mouseMove(volumeUp);
    emit buttonEntered(volumeUp);
    QTest::qWait(500);
    QTest::mouseClick(volumeUp,Qt::LeftButton);
    QTest::qWait(1000);
    KeyDialog * dialog=(KeyDialog *)volumeUp->getItem();
    QTest::keyPress(dialog,Qt::Key_Plus,Qt::NoModifier);
    QTest::mouseMove(cancelButton);
    emit buttonEntered(cancelButton);
    QTest::qWait(1000);
    QTest::mouseClick(cancelButton,Qt::LeftButton);
}

void ShortcutSettings::assertCancelled() {
    QCOMPARE(KeyBindings::volumeUpKey[0],(int)Qt::Key_Plus);
    QCOMPARE(KeyBindings::volumeUpKey[1],(int)Qt::ShiftModifier);
}

QString ShortcutSettings::getModifierString(int modifiers) {
    QString result="";
    QFlags<Qt::KeyboardModifier> modifierKeys=QFlags<Qt::KeyboardModifier>(modifiers);
    if(modifierKeys.testFlag(Qt::ShiftModifier)) {
        result+="Shift + ";
    }
    if(modifierKeys.testFlag(Qt::ControlModifier)) {
        #if defined(Q_OS_MAC)
            result+="Command + ";
        #else
                result+="Ctl + ";
        #endif
    }
    if(modifierKeys.testFlag(Qt::MetaModifier)) {
        #if defined(Q_OS_MAC)
            result+="Ctl + ";
        #else
            result+="Windows + ";
        #endif
    }
    if(modifierKeys.testFlag(Qt::AltModifier)) {
        result+="Alt + ";
    }
    return result;
}

void ShortcutSettings::updateShortcut(KeyDialog *dialog) {
    QLabel * label=hash.value(dialog);
    QString key="";
    int value=dialog->getText().toInt();
    switch(value) {
        case Qt::Key_Up:
            key+="Up";
        break;
        case Qt::Key_Down:
            key+="Down";
        break;
        case Qt::Key_Left:
            key+="Left";
        break;
        case Qt::Key_Right:
            key+="Right";
        break;
        case Qt::Key_Backspace:
            key+="Backspace";
        break;
        case Qt::Key_Delete:
            key+="Delete";
        break;
        case Qt::Key_Enter:
            key+="Enter";
        break;
        case Qt::Key_Return:
            key+="Enter";
        break;
        default:
            key+=(char)value;
            break;
    }

    label->setText(getModifierString(dialog->getModifiers())+"'"+key+"'");
}
